unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls, Grids, ImgList, jpeg,
  ExtCtrls, ToolWin, Menus, ActnList, formula, formulan;

type

  TMacro = record          
    name, text : string;
  end;

  TMainForm = class(TForm)
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    TabSheet3: TTabSheet;
    Label1: TLabel;
    text: TComboBox;
    Button3: TButton;
    Label6: TLabel;
    res: TEdit;
    Label2: TLabel;
    cnt: TEdit;
    Label5: TLabel;
    ud: TUpDown;
    Grd: TStringGrid;
    TestCB: TCheckBox;
    CaseCB: TCheckBox;
    Label4: TLabel;
    Button2: TButton;
    Button1: TButton;
    TabSheet4: TTabSheet;
    ImageList1: TImageList;
    Memo1: TMemo;
    Label3: TLabel;
    NI: TEdit;
    BM: TStringGrid;
    R: TButton;
    Bevel1: TBevel;
    Label7: TLabel;
    Image1: TImage;
    Bevel2: TBevel;
    Label8: TLabel;
    Label9: TLabel;
    Bevel3: TBevel;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    Label13: TLabel;
    Label14: TLabel;
    Label15: TLabel;
    Sel: TComboBox;
    Label16: TLabel;
    Script: TMemo;
    BRun: TButton;
    Label17: TLabel;
    SRes: TMemo;
    Editor: TRichEdit;
    ToolbarImages: TImageList;
    StandardToolBar: TToolBar;
    ToolButton1: TToolButton;
    OpenButton: TToolButton;
    SaveButton: TToolButton;
    PrintButton: TToolButton;
    CutButton: TToolButton;
    CopyButton: TToolButton;
    PasteButton: TToolButton;
    UndoButton: TToolButton;
    FontName: TComboBox;
    FontSize: TEdit;
    UpDown1: TUpDown;
    BoldButton: TToolButton;
    ItalicButton: TToolButton;
    UnderlineButton: TToolButton;
    ToolButton16: TToolButton;
    LeftAlign: TToolButton;
    CenterAlign: TToolButton;
    RightAlign: TToolButton;
    ToolButton20: TToolButton;
    BulletsButton: TToolButton;
    ToolButton3: TToolButton;
    ToolButton4: TToolButton;
    ToolButton7: TToolButton;
    ToolButton2: TToolButton;
    ToolButton5: TToolButton;
    ToolButton6: TToolButton;
    Ruler: TPanel;
    FirstInd: TLabel;
    LeftInd: TLabel;
    RulerLine: TBevel;
    RightInd: TLabel;
    Bevel4: TBevel;
    OpenDialog: TOpenDialog;
    SaveDialog: TSaveDialog;
    FontDialog1: TFontDialog;
    PrintDialog: TPrintDialog;
    ToolButton8: TToolButton;
    ToolButton9: TToolButton;
    ActionList1: TActionList;
    FileNewCmd: TAction;
    FileOpenCmd: TAction;
    FileSaveCmd: TAction;
    FilePrintCmd: TAction;
    FileSaveAsCmd: TAction;
    ActionList2: TActionList;
    EditUndoCmd: TAction;
    EditCutCmd: TAction;
    EditCopyCmd: TAction;
    EditPasteCmd: TAction;
    EditFontCmd: TAction;
    PopupMenu1: TPopupMenu;
    Copy1: TMenuItem;
    Cut1: TMenuItem;
    Paste1: TMenuItem;
    N1: TMenuItem;
    Undo1: TMenuItem;
    EditBoldCmd: TAction;
    EditItalicCmd: TAction;
    EditUnderlineCmd: TAction;
    MemoText: TMemo;
    procedure FormShow(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure cntChange(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure RClick(Sender: TObject);
    procedure Label13MouseEnter(Sender: TObject);
    procedure Label13MouseLeave(Sender: TObject);
    procedure Label13Click(Sender: TObject);
    procedure BRunClick(Sender: TObject);
    procedure SelChange(Sender: TObject);
    procedure FileSave(Sender: TObject);
    procedure FileSaveAs(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure SelectionChange(Sender: TObject);
    procedure RulerResize(Sender: TObject);
    procedure FileNew(Sender: TObject);
    procedure FileOpen(Sender: TObject);
    procedure FilePrint(Sender: TObject);
    procedure EditUndo(Sender: TObject);
    procedure EditCut(Sender: TObject);
    procedure EditCopy(Sender: TObject);
    procedure EditPaste(Sender: TObject);
    procedure FontNameChange(Sender: TObject);
    procedure EditFont(Sender: TObject);
    procedure BoldButtonClick(Sender: TObject);
    procedure ItalicButtonClick(Sender: TObject);
    procedure UnderlineButtonClick(Sender: TObject);
    procedure FontSizeChange(Sender: TObject);
    procedure LeftAlignClick(Sender: TObject);
    procedure BulletsButtonClick(Sender: TObject);
    procedure RightIndMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure RightIndMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FirstIndMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure LeftIndMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure RightIndMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure ActionList2Update(Action: TBasicAction;
      var Handled: Boolean);
    procedure ToolButton4Click(Sender: TObject);
    procedure TabSheet3Show(Sender: TObject);
    procedure EditBoldCmdExecute(Sender: TObject);
    procedure cute(Sender: TObject);
    procedure EditUnderlineCmdExecute(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure textChange(Sender: TObject);
  private
    FFileName: string;
    FUpdating: Boolean;
    FDragOfs: Integer;
    FDragging: Boolean;
    procedure LoadMacro;
    procedure SaveMacro;
    function CurrText: TTextAttributes;
    procedure GetFontNames;
    procedure CheckFileSave;
    procedure SetupRuler;
    procedure PerformFileOpen(const AFileName: string);
    procedure SetEditRect;
  public
    F: TArtFormula;
    FN: TArtFormulaN;
   Run : boolean;
   path : string;
   property FileName : string read FFileName write FFileName;
    { Public declarations }
  end;

var
  MainForm: TMainForm;
  Macro : array of TMacro;

implementation

uses  af_file, math, shellapi, richedit, macros;

{$R *.dfm}

const
 RulerAdj = 4/3;
 GutterWid = 6;
 programs : array [0..5] of string =
(

'begin'#13#10+
' var ''i'' end;'#13#10+
' while 1=1 do'#13#10+
'  $i++;'#13#10+
'  print("("+$i+") Press ""Stop"" button to stop!");'#13#10+ 
' wend'#13#10+
'end',

'begin'#13#10+
' var ''i'', ''t'' end;'#13#10+
' $t := now;'#13#10+
' print(''Wait 5 seconds...'');'#13#10+
' for $i:=1; $i<=5; $i++ do'#13#10+
'  while (now - $t) < 1/(24*60*60) do wend;'#13#10+
'  $t := now;'#13#10+
'  print($i+'' second'');'#13#10+
' next;'#13#10+
' print(''Ok!'');'#13#10+
'end',

'begin'#13#10+
'var "i","c","f","s" end;'#13#10+
'   print(''Centigrade to farenheight temperature table'');'#13#10+
'   print("");'#13#10+
'   for $i := -2; $i <= 12; $i++ do'#13#10+
'      $c := 10*$i;'#13#10+
'      $f := 32 + $c*9 div 5;'#13#10+
'      $s := ''  C ='' + formatf("%4.0f",$c) +'#13#10+
'            ''      F ='' + formatf("%4.0f",$f);'#13#10+
'      if $c = 0 then'#13#10+
'         $s := $s + ''  Freezing point of water'';'#13#10+
'      endif;'#13#10+
'      if $c = 100 then'#13#10+
'         $s := $s + ''  Boiling point of water'';'#13#10+
'      endif;'#13#10+
'      print($s);'#13#10+
'   next;'#13#10+
'end'
,

'begin'#13#10+
' print(''This is a TArtFormula Demo'');'#13#10+
' print(''======================'');'#13#10+
' print('''');'#13#10+
' var ''f'' end;'#13#10+
' $f := file.new;'#13#10+
' file($f).name := ''info'';'#13#10+
' file($f).open(''read'');'#13#10+
' while not file($f).eof do'#13#10+
'  print(file($f).readln);'#13#10+
' wend;'#13#10+
' file.freeall;'#13#10+
'end',

'begin'#13#10+
'  var "n","i","j","k","d" end;'#13#10+
'   $n := input("Input dimension","Dimension of matrix:",3);'#13#10+
#13#10+
'   for $i:=1; $i <= $n; $i++ do'#13#10+
'         for $j:=1; $j <= $n; $j++ do'#13#10+
' 	var "a"+$i+"_"+$j end;'#13#10+
'            $a[$i,$j] := input("Input element","a["+$i+","+$j+"] = ",if $i = $j ; 1 ; 0 end);'#13#10+
'         next;'#13#10+
'   next;'#13#10+
#13#10+
'    for $i:=1; $i <= $n; $i++ do'#13#10+
'       var "b"+$i, "x"+$i end;'#13#10+
'       $b[$i] := input("Input element","b["+$i+"] = ",1);'#13#10+
'    next;'#13#10+
#13#10+
'    for $i:=1; $i < $n; $i++ do'#13#10+
'         for $k:=$i+1; $k <= $n; $k++ do'#13#10+
'             $d:=$a[$k,$i]/$a[$i,$i];'#13#10+
'             for $j:=$i+1; $j <= $n; $j++;'#13#10+
'               $a[$k,$j]:=$a[$k,$j]-$a[$i,$j]*$d;'#13#10+
'             end;'#13#10+
'             $b[$k]:=$b[$k]-$b[$i]*$d;'#13#10+
'         next;'#13#10+
'    next;'#13#10+
#13#10+
'    for $i:=$n; $i >= 1; $i-- do'#13#10+
'         for $j:=$i+1; $j <= $n; $j++;'#13#10+
'            $b[$i]:=$b[$i]-$a[$i,$j]*$x[$j];'#13#10+
'         end;'#13#10+
'         $x[$i]:=$b[$i]/$a[$i,$i];'#13#10+
'    next;'#13#10+
'    print("Result:");'#13#10+
'    for $i:=1; $i <= $n; $i++;  print("x["+$i+"] = "+$x[$i]); end;'#13#10+
#13#10+
'end',


'begin'#13#10+
'var ''in'', ''n'', ''a'', ''b'', ''j'' end;'#13#10+
' $in := input(''Prime test'',''Input positive number'',10);'#13#10+
' if not isnumber($in) or ($n < 1) then'#13#10+
'  msg(''Bad number'',''Error'',$10)'#13#10+
' else'#13#10+
'  $n := 1;'#13#10+
'  for $a := 2; $a <= $in; $a++ do'#13#10+
'   $b := true;'#13#10+
'   for $j := 1; $j < $n; $j++ do'#13#10+
'    if ($a mod $p[$j]) = 0 then'#13#10+
'        $b := false;'#13#10+
'  	 $j := $n+1;'#13#10+
'     endif;'#13#10+
'   next;'#13#10+
'   if $b then'#13#10+
'    define(''p''@$n, $a);'#13#10+
'    $n++;'#13#10+
'   endif;'#13#10+
'  next;'#13#10+
'  print(''Prime numbers in [2..''+$in+''] are:'');'#13#10+
'  for $j:=1; $j<$n; $j++; print(''   ''@$p[$j]) end;'#13#10+
'  print(''Found ''+($n-1)+'' primes'');'#13#10+
' endd;'#13#10+
'end'

);

function mytestfn(var Calc: TFormulaCalc): TCalcItem;
begin
  // Set strign result with top stack item passed as parameter
  setS(result, 'LANG=' + Calc.TopS + '.');
end;

function mytestfncount(var Calc: TFormulaCalc): TCalcItem;
begin
  // Set integer result with top stack item passed as parameter (not used)
//  setS(result, 'LANG=' + Calc.TopS + '.');
  setN(result, 20);
end;

function myabout(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.PageControl1.ActivePageIndex := 3;
 setN(result,0);
end;

function myprint(var Calc : TFormulaCalc):TCalcItem;
begin
 Mainform.SRes.Lines.Add(Calc.TopS);
 setN(result,0);
end;

procedure TMainForm.Button1Click(Sender: TObject);
begin
 grd.RowCount := grd.RowCount + 1;
 ud.Position := grd.RowCount - 1;
end;

procedure TMainForm.Button2Click(Sender: TObject);
begin
 if grd.RowCount > 2 then
  grd.RowCount := grd.RowCount - 1;
 ud.Position := grd.RowCount - 1;
end;

procedure TMainForm.cntChange(Sender: TObject);
begin
 ud.Position := strtointdef(cnt.Text,0);
end;

procedure TMainForm.Button3Click(Sender: TObject);
var vars : array of string;
    vals : TCalcArray;
//    vals : DoubleArray;
    i,num : integer;
begin
 num := ud.Position;
 F.CaseSensitive := casecb.Checked;
 F.TestUsedVars := testcb.Checked;
 if num > 0 then
 begin
  setlength(vals,num);
  setlength(vars,num);
  for i := 0 to num - 1 do
  begin
   vars[i] := grd.Cells[0,i+1];
   setN(vals[i],strtofloatdef(grd.Cells[1,i+1],0));
//   vals[i] := strtofloatdef(grd.Cells[1,i+1],0);
  end;
 end;
 try
  res.Text := F.ComputeStr(MemoText.Text,num, @vars,@vals);
//  res.Text := floattostr(FN.ComputeStr(MemoText.Text,@vars,num,@vals));
 except
  on E:Exception do
  begin
   Application.MessageBox(pchar(E.Message),'Error',mb_iconstop);
   ActiveControl := text;
   text.SelStart := F.ErrPos-1;
  end;
 end;

end;


{$O-}
procedure TMainForm.RClick(Sender: TObject);
var t1, t2 : TTime;
    x : double;
    i,n : integer;
    s : string;
begin
 if run then
 begin
  R.Caption := 'Run';
  run := false;
  F.Stop := true;
 end
 else
 begin
  F.Step := false;
  n := strtointdef(NI.Text,1000000);
  R.Caption := 'Stop';
  run := true;
  BM.RowCount := 2;
  BM.FixedRows := 1;
  BM.Cells[1,0] := '  Machine code';
  BM.Cells[2,0] := '  TArtFormulaN';
  BM.Cells[3,0] := '  TArtFormula';
  BM.Cells[1,1] := '';
  BM.Cells[2,1] := '';
  BM.Cells[3,1] := '';

  s := '  (3-Pi/2)*Pi+3.5^3.2';
  BM.Cells[0,1] := s;
  Application.ProcessMessages;
  if not run then exit;

  t1 := time;
  for i := 1 to n do
  begin
   x := (3-Pi/2)*Pi+power(3.5,3.2);
  end;
  t2 := time;

  BM.Cells[1,1] := formatdatetime('ss:zzz',t2-t1);
  Application.ProcessMessages;
  if not run then exit;

  FN.Compile(s);
  t1 := time;
  for i := 1 to n do
  begin
   FN.Compute(nil);
  end;
  t2 := time;

  BM.Cells[2,1] := formatdatetime('ss:zzz',t2-t1);
  Application.ProcessMessages;
  if not run then exit;

  F.Compile(s);
  t1 := time;
  for i := 1 to n do
  begin
   F.ComputeN;
  end;
  t2 := time;

  BM.Cells[3,1] := formatdatetime('ss:zzz',t2-t1);
  Application.ProcessMessages;
  if not run then exit;


  BM.RowCount := 3;
  BM.Cells[1,2] := '';
  BM.Cells[2,2] := '';
  BM.Cells[3,2] := '';
  s := '  sin(sqrt(atan(3)))';
  BM.Cells[0,2] := s;
  Application.ProcessMessages;
  if not run then exit;

  t1 := time;
  for i := 1 to n do
  begin
    x := sin(sqrt(arctan(3)));
  end;
  t2 := time;

  BM.Cells[1,2] := formatdatetime('ss:zzz',t2-t1);
  Application.ProcessMessages;
  if not run then exit;

  FN.Compile(s);
  t1 := time;
  for i := 1 to n do
  begin
    FN.Compute(nil);
  end;
  t2 := time;

  BM.Cells[2,2] := formatdatetime('ss:zzz',t2-t1);
  Application.ProcessMessages;
  if not run then exit;

  F.Compile(s);
  t1 := time;
  for i := 1 to n do
  begin
   F.ComputeN;
  end;
  t2 := time;

  BM.Cells[3,2] := formatdatetime('ss:zzz',t2-t1);
  Application.ProcessMessages;
  if not run then exit;

  BM.RowCount := 4;
  BM.Cells[1,3] := '';
  BM.Cells[2,3] := '';
  BM.Cells[3,3] := '';
  s := '  midstr(trim(" 12345"@" "),2,3)';
  BM.Cells[0,3] := s;
  Application.ProcessMessages;
  if not run then exit;

  t1 := time;
  for i := 1 to n do
  begin
   copy(trim(' 12345'+' '),2,3);
  end;
  t2 := time;

  BM.Cells[1,3] := formatdatetime('ss:zzz',t2-t1);
  BM.Cells[2,3] := 'Not supported';
  Application.ProcessMessages;
  if not run then exit;

  F.Compile(s);
  t1 := time;
  for i := 1 to n do
  begin
   F.Compute;
  end;
  t2 := time;

  BM.Cells[3,3] := formatdatetime('ss:zzz',t2-t1);
  Application.ProcessMessages;
  if not run then exit;
  run := false;
  R.Caption := 'Run';
 end;

end;
{$O+}

procedure TMainForm.Label13MouseEnter(Sender: TObject);
begin
(sender as TLabel).Font.Style := [fsunderline];
end;

procedure TMainForm.Label13MouseLeave(Sender: TObject);
begin
(sender as TLabel).Font.Style := [];
end;

procedure TMainForm.Label13Click(Sender: TObject);
begin
 ShellExecute(handle,'open',pchar((sender as TLabel).Caption),'','',sw_show)
end;

procedure TMainForm.BRunClick(Sender: TObject);
begin
 if run then
 begin
  BRun.Caption := 'Run';
  run := false;
  F.Stop := true;
 end
 else
 begin
  F.Step := true;
  BRun.Caption := 'Stop';
  run := true;
  SRes.Clear;
  Application.ProcessMessages;
  try
   F.ComputeStr(Script.Text);
  except
   on E: Exception do
   begin
    Application.MessageBox(pchar(E.Message),'Error',mb_iconstop);
    ActiveControl := Script;
    Script.SelStart := F.ErrStrPos;
   end;
  end;
  BRun.Caption := 'Run';
  run := false;
 end;
end;

//  RichEditor (based on Demos RichEdit project)

procedure TMainForm.SelChange(Sender: TObject);
begin
 Script.Text := programs[Sel.itemindex];
end;

function EnumFontsProc(var LogFont: TLogFont; var TextMetric: TTextMetric;
  FontType: Integer; Data: Pointer): Integer; stdcall;
begin
  TStrings(Data).Add(LogFont.lfFaceName);
  Result := 1;
end;

procedure TMainForm.GetFontNames;
var
  DC: HDC;
begin
  DC := GetDC(0);
  EnumFonts(DC, nil, @EnumFontsProc, Pointer(FontName.Items));
  ReleaseDC(0, DC);
  FontName.Sorted := True;
end;

function TMainForm.CurrText: TTextAttributes;
begin
 Result := Editor.SelAttributes
end;

procedure TMainForm.CheckFileSave;
var
  SaveResp: Integer;
begin
  if not Editor.Modified then Exit;
  SaveResp := Application.MessageBox(pchar(Format('Save changes to %s?', [FFileName])),
    'Save', mb_iconquestion + mb_YesNoCancel);
  case SaveResp of
    idYes: FileSave(Self);
    idCancel: Abort;
  end;
end;

procedure TMainForm.SetupRuler;
var
  I: Integer;
  S: String;
begin
  SetLength(S, 201);
  I := 1;
  while I < 200 do
  begin
    S[I] := #9;
    S[I+1] := '|';
    Inc(I, 2);
  end;
  Ruler.Caption := S;
end;

procedure TMainForm.FileSave(Sender: TObject);
begin
  if FFileName = 'Untitled' then
    FileSaveAs(Sender)
  else
  begin
    Editor.Lines.SaveToFile(FFileName);
    Editor.Modified := False;
  end;
end;

procedure TMainForm.FileSaveAs(Sender: TObject);
begin
  if SaveDialog.Execute then
  begin
    if FileExists(SaveDialog.FileName) then
      if MessageDlg(Format('Overwrite %s?', [SaveDialog.FileName]),
        mtConfirmation, mbYesNoCancel, 0) <> idYes then Exit;
    Editor.Lines.SaveToFile(SaveDialog.FileName);
    FFileName := SaveDialog.FileName;
    Editor.Modified := False;
  end;
end;

procedure TMainForm.PerformFileOpen(const AFileName: string);
begin
  Editor.Lines.LoadFromFile(AFileName);
  FFileName := AFileName;
  Editor.SetFocus;
  Editor.Modified := False;
end;

procedure TMainForm.SetEditRect;
var
  R: TRect;
begin
  with Editor do
  begin
    R := Rect(GutterWid, 0, ClientWidth-GutterWid, ClientHeight);
    SendMessage(Handle, EM_SETRECT, 0, Longint(@R));
  end;
end;


procedure TMainForm.FormResize(Sender: TObject);
begin
  SetEditRect;
  SelectionChange(Sender);
end;

procedure TMainForm.FormPaint(Sender: TObject);
begin
  SetEditRect;
end;

procedure TMainForm.SelectionChange(Sender: TObject);
begin
  with Editor.Paragraph do
  try
    FUpdating := True;
    FirstInd.Left := Trunc(FirstIndent*RulerAdj)-4+GutterWid;
    LeftInd.Left := Trunc((LeftIndent+FirstIndent)*RulerAdj)-4+GutterWid;
    RightInd.Left := Ruler.ClientWidth-6-Trunc((RightIndent+GutterWid)*RulerAdj);
    BoldButton.Down := fsBold in Editor.SelAttributes.Style;
    ItalicButton.Down := fsItalic in Editor.SelAttributes.Style;
    UnderlineButton.Down := fsUnderline in Editor.SelAttributes.Style;
    BulletsButton.Down := Boolean(Numbering);
    FontSize.Text := IntToStr(Editor.SelAttributes.Size);
    FontName.Text := Editor.SelAttributes.Name;
    case Ord(Alignment) of
      0: LeftAlign.Down := True;
      1: RightAlign.Down := True;
      2: CenterAlign.Down := True;
    end;
  finally
    FUpdating := False;
  end;
end;

procedure TMainForm.RulerResize(Sender: TObject);
begin
  RulerLine.Width := Ruler.ClientWidth - (RulerLine.Left*2);
end;

procedure TMainForm.FileNew(Sender: TObject);
begin
  CheckFileSave;
  FFileName := 'Untitled';
  Editor.Lines.Clear;
  Editor.Modified := False;
end;

procedure TMainForm.FileOpen(Sender: TObject);
begin
  CheckFileSave;
  if OpenDialog.Execute then
  begin
    PerformFileOpen(OpenDialog.FileName);
    Editor.ReadOnly := ofReadOnly in OpenDialog.Options;
  end;
end;

procedure TMainForm.FilePrint(Sender: TObject);
begin
  if PrintDialog.Execute then
    Editor.Print(FFileName);
end;

procedure TMainForm.EditUndo(Sender: TObject);
begin
  with Editor do
    if HandleAllocated then SendMessage(Handle, EM_UNDO, 0, 0);
end;

procedure TMainForm.EditCut(Sender: TObject);
begin
 Editor.CutToClipboard;
end;

procedure TMainForm.EditCopy(Sender: TObject);
begin
 Editor.CopyToClipboard;
end;

procedure TMainForm.EditPaste(Sender: TObject);
begin
 Editor.PasteFromClipboard;
end;

procedure TMainForm.FontNameChange(Sender: TObject);
begin
  if FUpdating then Exit;
  CurrText.Name := FontName.Items[FontName.ItemIndex];
end;

procedure TMainForm.EditFont(Sender: TObject);
begin
  FontDialog1.Font.Assign(Editor.SelAttributes);
  if FontDialog1.Execute then
    CurrText.Assign(FontDialog1.Font);
  SelectionChange(Self);
  Editor.SetFocus;
end;

procedure TMainForm.BoldButtonClick(Sender: TObject);
begin
  if FUpdating then Exit;
  if BoldButton.Down then
    CurrText.Style := CurrText.Style + [fsBold]
  else
    CurrText.Style := CurrText.Style - [fsBold];
end;

procedure TMainForm.ItalicButtonClick(Sender: TObject);
begin
  if FUpdating then Exit;
  if ItalicButton.Down then
    CurrText.Style := CurrText.Style + [fsItalic]
  else
    CurrText.Style := CurrText.Style - [fsItalic];
end;

procedure TMainForm.UnderlineButtonClick(Sender: TObject);
begin
  if FUpdating then Exit;
  if UnderlineButton.Down then
    CurrText.Style := CurrText.Style + [fsUnderline]
  else
    CurrText.Style := CurrText.Style - [fsUnderline];
end;

procedure TMainForm.TabSheet3Show(Sender: TObject);
begin
 Activecontrol := Editor;
end;

procedure TMainForm.EditBoldCmdExecute(Sender: TObject);
begin
 BoldButton.Down := not BoldButton.Down;
 BoldButtonClick(Self);
end;

procedure TMainForm.cute(Sender: TObject);
begin
 ItalicButton.Down := not ItalicButton.Down;
 ItalicButtonClick(Self);
end;

procedure TMainForm.EditUnderlineCmdExecute(Sender: TObject);
begin
 UnderlineButton.Down := not UnderlineButton.Down;
 UnderlineButtonClick(Self);
end;

procedure TMainForm.FontSizeChange(Sender: TObject);
begin
  if FUpdating then Exit;
  CurrText.Size := StrToInt(FontSize.Text);
end;

procedure TMainForm.LeftAlignClick(Sender: TObject);
begin
  if FUpdating then Exit;
  Editor.Paragraph.Alignment := TAlignment(TControl(Sender).Tag);
end;

procedure TMainForm.BulletsButtonClick(Sender: TObject);
begin
  if FUpdating then Exit;
  Editor.Paragraph.Numbering := TNumberingStyle(BulletsButton.Down);
end;

procedure TMainForm.RightIndMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  FDragOfs := (TLabel(Sender).Width div 2);
  TLabel(Sender).Left := TLabel(Sender).Left+X-FDragOfs;
  FDragging := True;
end;

procedure TMainForm.RightIndMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
  if FDragging then
    TLabel(Sender).Left :=  TLabel(Sender).Left+X-FDragOfs
end;

procedure TMainForm.FirstIndMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FDragging := False;
  Editor.Paragraph.FirstIndent := Trunc((FirstInd.Left+FDragOfs-GutterWid) / RulerAdj);
  LeftIndMouseUp(Sender, Button, Shift, X, Y);
end;

procedure TMainForm.LeftIndMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FDragging := False;
  Editor.Paragraph.LeftIndent := Trunc((LeftInd.Left+FDragOfs-GutterWid) / RulerAdj)-Editor.Paragraph.FirstIndent;
  SelectionChange(Sender);
end;

procedure TMainForm.RightIndMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FDragging := False;
  Editor.Paragraph.RightIndent := Trunc((Ruler.ClientWidth-RightInd.Left+FDragOfs-2) / RulerAdj)-2*GutterWid;
  SelectionChange(Sender);
end;

procedure TMainForm.ActionList2Update(Action: TBasicAction;
  var Handled: Boolean);
begin
  EditCutCmd.Enabled := Editor.SelLength > 0;
  EditCopyCmd.Enabled := EditCutCmd.Enabled;
  if Editor.HandleAllocated then
  begin
    EditUndoCmd.Enabled := Editor.Perform(EM_CANUNDO, 0, 0) <> 0;
    EditPasteCmd.Enabled := Editor.Perform(EM_CANPASTE, 0, 0) <> 0;
  end;
end;

// Macro Implementation

procedure TMainForm.LoadMacro;
var F:TextFile;
    s : string;
    i : integer;
begin
 Macro := nil;
 if not fileexists(path+'macros') then
 begin
  Editor.Clear;
  Editor.Paragraph.Alignment := taCenter;
  Editor.SelAttributes.Name := 'Arial';
  Editor.SelAttributes.Size := 18;
  Editor.SelAttributes.Color := clRed;
  Editor.SelText := #13'File ';
  Editor.SelAttributes.Style := [fsbold];
  Editor.Seltext := 'macro ';
  Editor.SelAttributes.Style := [];
  Editor.Seltext := 'not found!';
  exit;
 end;
 AssignFile(F,path+'macros');
 reset(F);
 i := -1;
 while not eof(F) do
 begin
  readln(F,s);
  if copy(s,1,2) = '##' then
  begin
   inc(i);
   setlength(Macro,i+1);
   Macro[i].name := copy(s,4,length(s)-6);
   Macro[i].text := '';
   continue;
  end;
  if i >= 0 then
  begin
   s := s+#13#10;
   Macro[i].text := Macro[i].text + s;
  end;
 end;
 CloseFile(F);
end;

procedure TMainForm.SaveMacro;
var F:TextFile;
    i : integer;
begin
 AssignFile(F,path+'macros');
 rewrite(F);
 for i := 0 to high(Macro) do
 begin
  writeln(F,'## '+Macro[i].name+' ##');
  write(F,Macro[i].text);
 end;
 CloseFile(F);
end;

procedure TMainForm.ToolButton4Click(Sender: TObject);
var i:integer;
begin
 LoadMacro;
 MacrosForm.Macros.Clear;
 for i:=0 to high(Macro) do MacrosForm.Macros.AddItem(Macro[i].name,TObject(i));
 MacrosForm.Macros.ItemIndex := 0;
 MacrosForm.Showmodal;
 SaveMacro;
end;

function mydocnew(var Calc : TFormulaCalc):TCalcItem;
begin
 if Calc.TopN > 0 then
 begin
  Mainform.FileName := 'Untitled';
  MainForm.Editor.Lines.Clear;
  MainForm.Editor.Modified := False;
 end
 else
  MainForm.FileNew(nil);
 setN(result,0);
end;

function mydocfilename(var Calc : TFormulaCalc):TCalcItem;
begin
 setS(result,MainForm.FileName);
end;

function mydocsetfilename(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.FileName := Calc.TopS;
 setN(result,0);
end;

function mydocsave(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.Lines.SaveToFile(Calc.TopS);
 MainForm.Editor.Modified := False;
 setN(result,0);
end;

function mydocopen(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.PerformFileOpen(Calc.TopS);
 setN(result,0);
end;

function mydocprint(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.FilePrint(nil);
 setN(result,0);
end;

function mydocundo(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.EditUndo(nil);
 setN(result,0);
end;

function mydoccopy(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.EditCopy(nil);
 setN(result,0);
end;

function mydocpaste(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.EditPaste(nil);
 setN(result,0);
end;

function mydoccut(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.EditCut(nil);
 setN(result,0);
end;

function mydoctypetext(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.SelText := Calc.TopS;
 setN(result,0);
end;

function mydoctypeparagraph(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.Perform(WM_CHAR,13,0);
 setN(result,0);
end;

function mydocfontname(var Calc : TFormulaCalc):TCalcItem;
begin
 setS(result,MainForm.Editor.defattributes.name);
end;

function mydocsetfontname(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.defattributes.name := Calc.TopS;
 setN(result,0);
end;

function mydocfontsize(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,MainForm.Editor.defattributes.size);
end;

function mydocsetfontsize(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.defattributes.size := trunc(Calc.TopN);
 setN(result,0);
end;

function mydocfontcolor(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,MainForm.Editor.defattributes.color);
end;

function mydocsetfontcolor(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.defattributes.color := trunc(Calc.TopN);
 setN(result,0);
end;

function mydocclear(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.Clear;
 setN(result,0);
end;

function mydocselectall(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.SelectAll;
 setN(result,0);
end;

function mydocselect(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.SelStart := trunc(Calc.ItemN(1)-1);
 MainForm.Editor.SelLength := trunc(Calc.topn);
 setN(result,0);
end;

function mydocposx(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,(MainForm.Editor.SelStart -
    SendMessage(MainForm.Editor.Handle, EM_LINEINDEX,
    SendMessage(MainForm.Editor.Handle, EM_EXLINEFROMCHAR, 0,
    MainForm.Editor.SelStart), 0))+1);
end;

function mydocsetpos(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.SelStart :=
 SendMessage(MainForm.Editor.Handle,EM_LINEINDEX, trunc(Calc.topn)-1,0)+
 trunc(calc.ItemN(1))-1;
 setN(result, 0);
end;

function mydoctext(var Calc : TFormulaCalc):TCalcItem;
begin
 setS(result, MainForm.Editor.Text);
end;

function mydocsettext(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.Text := Calc.TopS;
 setS(result, Calc.TopS);
end;


function mydoclinecount(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,MainForm.Editor.Lines.Count);
end;

function mydoclineindex(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,SendMessage(MainForm.Editor.Handle,EM_LINEINDEX, trunc(Calc.topn)-1,0));
end;

function mydocline(var Calc : TFormulaCalc):TCalcItem;
begin
 setS(result,MainForm.Editor.Lines[trunc(Calc.TopN) + 1]);
end;

function mydocposy(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,SendMessage(MainForm.Editor.Handle, EM_EXLINEFROMCHAR, 0,
    MainForm.Editor.SelStart)+1);
end;

function mydocfontbold(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,ifthen(fsbold in MainForm.Editor.defattributes.style,1,0));
end;

function mydocsetfontbold(var Calc : TFormulaCalc):TCalcItem;
begin
 if Calc.TopN <> 0 then
  MainForm.Editor.defattributes.style :=
   MainForm.Editor.defattributes.style + [fsbold]
 else
  MainForm.Editor.defattributes.style :=
   MainForm.Editor.defattributes.style - [fsbold];
 setN(result,0);
end;

function mydocfontitalic(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,ifthen(fsitalic in MainForm.Editor.defattributes.style,1,0));
end;

function mydocsetfontitalic(var Calc : TFormulaCalc):TCalcItem;
begin
 if Calc.TopN <> 0 then
  MainForm.Editor.defattributes.style :=
   MainForm.Editor.defattributes.style + [fsitalic]
 else
  MainForm.Editor.defattributes.style :=
   MainForm.Editor.defattributes.style - [fsitalic];
 setN(result,0);
end;

function mydocfontunderline(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,ifthen(fsunderline in MainForm.Editor.defattributes.style,1,0));
end;

function mydocsetfontunderline(var Calc : TFormulaCalc):TCalcItem;
begin
 if Calc.TopN <> 0 then
  MainForm.Editor.defattributes.style :=
   MainForm.Editor.defattributes.style + [fsunderline]
 else
  MainForm.Editor.defattributes.style :=
   MainForm.Editor.defattributes.style - [fsunderline];
 setN(result,0);
end;

function myparnumbering(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,integer(MainForm.Editor.Paragraph.Numbering));
end;

function myparsetnumbering(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.Paragraph.Numbering := TNumberingStyle(trunc(Calc.topN));
 setN(result,0);
end;

function myparalign(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,integer(MainForm.Editor.Paragraph.Alignment));
end;

function myparsetalign(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.Paragraph.Alignment := TAlignment(trunc(Calc.topN));
 setN(result,0);
end;

function myparfirstindent(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,integer(MainForm.Editor.Paragraph.FirstIndent));
end;

function myparsetfirstindent(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.Paragraph.FirstIndent := trunc(Calc.topN);
 setN(result,0);
end;

function myparleftindent(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,integer(MainForm.Editor.Paragraph.leftIndent));
end;

function myparsetleftindent(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.Paragraph.leftIndent := trunc(Calc.topN);
 setN(result,0);
end;

function myparrightindent(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,integer(MainForm.Editor.Paragraph.rightIndent));
end;

function myparsetrightindent(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.Paragraph.rightindent := trunc(Calc.topN);
 setN(result,0);
end;

function myselfontbold(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,ifthen(fsbold in MainForm.Editor.selattributes.style,1,0));
end;

function myselsetfontbold(var Calc : TFormulaCalc):TCalcItem;
begin
 if Calc.TopN <> 0 then
  MainForm.Editor.selattributes.style :=
   MainForm.Editor.selattributes.style + [fsbold]
 else
  MainForm.Editor.selattributes.style :=
   MainForm.Editor.selattributes.style - [fsbold];
 setN(result,0);
end;

function myselfontitalic(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,ifthen(fsitalic in MainForm.Editor.selattributes.style,1,0));
end;

function myselsetfontitalic(var Calc : TFormulaCalc):TCalcItem;
begin
 if Calc.TopN <> 0 then
  MainForm.Editor.selattributes.style :=
   MainForm.Editor.selattributes.style + [fsitalic]
 else
  MainForm.Editor.selattributes.style :=
   MainForm.Editor.selattributes.style - [fsitalic];
 setN(result,0);
end;

function myselfontunderline(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,ifthen(fsunderline in MainForm.Editor.selattributes.style,1,0));
end;

function myselsetfontunderline(var Calc : TFormulaCalc):TCalcItem;
begin
 if Calc.TopN <> 0 then
  MainForm.Editor.selattributes.style :=
   MainForm.Editor.selattributes.style + [fsunderline]
 else
  MainForm.Editor.selattributes.style :=
   MainForm.Editor.selattributes.style - [fsunderline];
 setN(result,0);
end;

function myselfontname(var Calc : TFormulaCalc):TCalcItem;
begin
 setS(result,MainForm.Editor.selattributes.name);
end;

function myselsetfontname(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.selattributes.name := Calc.TopS;
 setN(result,0);
end;

function myselfontsize(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,MainForm.Editor.selattributes.size);
end;

function myselsetfontsize(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.selattributes.size := trunc(Calc.TopN);
 setN(result,0);
end;

function myselfontcolor(var Calc : TFormulaCalc):TCalcItem;
begin
 setN(result,MainForm.Editor.selattributes.color);
end;

function myselsetfontcolor(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.selattributes.color := trunc(Calc.TopN);
 setN(result,0);
end;

function myseltext(var Calc : TFormulaCalc):TCalcItem;
begin
 setS(result,MainForm.Editor.SelText);
end;

function myselsettext(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.SelText := Calc.tops;
 setN(result,0);
end;

function mydocclearselection(var Calc : TFormulaCalc):TCalcItem;
begin
 MainForm.Editor.SelStart := MainForm.Editor.SelStart +
          MainForm.Editor.Sellength;
 setN(result,0);
end;

procedure TMainForm.FormShow(Sender: TObject);
var module : PTableItem;
    i:integer;
begin
 run := false;
 path := ExtractFilePath(Paramstr(0));

 BM.ColWidths[0] := 160;
 BM.ColWidths[1] := 80;
 BM.ColWidths[2] := 80;
 BM.ColWidths[2] := 80;

 grd.Cells[0,0] := 'Name';
 grd.Cells[1,0] := 'Value';
 grd.Cells[0,1] := 'x';
 grd.Cells[1,1] := '7';
 grd.Cells[0,2] := 'y';
 grd.Cells[1,2] := '2';

 GetFontNames;
 OpenDialog.InitialDir := path;
 SaveDialog.InitialDir := OpenDialog.InitialDir;
 FFileName := 'Untitled';
 GetFontNames;
 SetupRuler;
 SelectionChange(Self);
 Editor.Modified := False;

 F.Step := true;
 module := F.AddUserFunction('test',1,mytestfn,true); // our test module & default fn.
 F.AddModuleFunction(module,'count',1,mytestfncount); // our test alternate fn.
 F.AddUserFunction('about',0,myabout,false);
 F.AddUserFunction('print',1,myprint,false);
 F.AddUserConstant('myarray','1,2,3,4,5');

 module := F.AddUserFunction('document',0,nil,true);
 F.AddModuleFunction(module,'new',1,mydocnew);
 F.AddModuleFunction(module,'filename',0,mydocfilename);
 F.AddModuleFunction(module,'setfilename',1,mydocsetfilename);
 F.AddModuleFunction(module,'save',1,mydocsave);
 F.AddModuleFunction(module,'open',1,mydocopen);
 F.AddModuleFunction(module,'print',0,mydocprint);
 F.AddModuleFunction(module,'undo',0,mydocundo);
 F.AddModuleFunction(module,'copy',0,mydoccopy);
 F.AddModuleFunction(module,'paste',0,mydocpaste);
 F.AddModuleFunction(module,'cut',0,mydoccut);
 F.AddModuleFunction(module,'typetext',1,mydoctypetext);
 F.AddModuleFunction(module,'typeparagraph',0,mydoctypeparagraph);
 F.AddModuleFunction(module,'fontname,e',0,mydocfontname);
 F.AddModuleFunction(module,'setfontname',1,mydocsetfontname);
 F.AddModuleFunction(module,'fontsize',0,mydocfontsize);
 F.AddModuleFunction(module,'setfontsize',1,mydocsetfontsize);
 F.AddModuleFunction(module,'fontcolor',0,mydocfontcolor);
 F.AddModuleFunction(module,'setfontcolor',1,mydocsetfontcolor);
 F.AddModuleFunction(module,'clear',0,mydocclear);
 F.AddModuleFunction(module,'selectall',0,mydocselectall);
 F.AddModuleFunction(module,'select',2,mydocselect);
 F.AddModuleFunction(module,'posx',0,mydocposx);
 F.AddModuleFunction(module,'setpos',2,mydocsetpos);
 F.AddModuleFunction(module,'linecount',0,mydoclinecount);
 F.AddModuleFunction(module,'lineindex',1,mydoclineindex);
 F.AddModuleFunction(module,'line',1,mydocline);
 F.AddModuleFunction(module,'posy',0,mydocposy);
 F.AddModuleFunction(module,'fontbold',0,mydocfontbold);
 F.AddModuleFunction(module,'setfontbold',1,mydocsetfontbold);
 F.AddModuleFunction(module,'fontitalic',0,mydocfontitalic);
 F.AddModuleFunction(module,'setfontitalic',1,mydocsetfontitalic);
 F.AddModuleFunction(module,'fontunderline',0,mydocfontunderline);
 F.AddModuleFunction(module,'setfontunderline',1,mydocsetfontunderline);
 F.AddModuleFunction(module,'text',0,mydoctext);
 F.AddModuleFunction(module,'settext',1,mydoctext);
 F.AddModuleFunction(module,'clearselection',0,mydocclearselection);

 module := F.AddUserFunction('paragraph',0,nil,true);
 F.AddModuleFunction(module,'numbering',0,myparnumbering);
 F.AddModuleFunction(module,'setnumbering',1,myparsetnumbering);
 F.AddModuleFunction(module,'align',0,myparalign);
 F.AddModuleFunction(module,'setalign',1,myparsetalign);
 F.AddModuleFunction(module,'firstindent',0,myparfirstindent);
 F.AddModuleFunction(module,'setfirstindent',1,myparsetfirstindent);
 F.AddModuleFunction(module,'leftindent',0,myparleftindent);
 F.AddModuleFunction(module,'setleftindent',1,myparsetleftindent);
 F.AddModuleFunction(module,'rightindent',0,myparrightindent);
 F.AddModuleFunction(module,'setrightindent',1,myparsetrightindent);

 module := F.AddUserFunction('selection',0,nil,true);
 F.AddModuleFunction(module,'fontbold',0,myselfontbold);
 F.AddModuleFunction(module,'setfontbold',1,myselsetfontbold);
 F.AddModuleFunction(module,'fontitalic',0,myselfontitalic);
 F.AddModuleFunction(module,'setfontitalic',1,myselsetfontitalic);
 F.AddModuleFunction(module,'fontunderline',0,myselfontunderline);
 F.AddModuleFunction(module,'setfontunderline',1,myselsetfontunderline);
 F.AddModuleFunction(module,'fontname',0,myselfontname);
 F.AddModuleFunction(module,'setfontname',1,myselsetfontname);
 F.AddModuleFunction(module,'fontsize',0,myselfontsize);
 F.AddModuleFunction(module,'setfontsize',1,myselsetfontsize);
 F.AddModuleFunction(module,'fontcolor',0,myselfontcolor);
 F.AddModuleFunction(module,'setfontcolor',1,myselsetfontcolor);
 F.AddModuleFunction(module,'text',0,myseltext);
 F.AddModuleFunction(module,'settext',1,myselsettext);

 AF_file.Install(F);
 LoadMacro;
 for i := 0 to high(macro) do
  if Uppercase(macro[i].name) = 'AUTOSTART' then
  begin
   F.ComputeStr(macro[i].text);
   break;
  end;
end;


procedure TMainForm.FormCreate(Sender: TObject);
begin
    F := TArtFormula.Create(Self);
    F.CaseSensitive := True;
    F.UnQuotedString := True; // allow unquoted string literals
    FN := TArtFormulaN.Create(Self);
end;

procedure TMainForm.textChange(Sender: TObject);
begin
MemoText.Text := Text.Text;
end;

end.
